#include "include/vesa.h"
#include "app/libdraw/draw.h"

extern const char fonts_zh[2][32]; // defined in app/libdraw/fonts.c
extern const char fonts_en[6][16];

/**
 * Draw english character function
 * 
 * @param o_x     Origin point o_x of the upper left corner of the rectangle
 * @param o_y     Origin point o_y of the upper left corner of the rectangle
 * @param index   Index of fonts characters array
 * @param color
 * @param fbbase
 * @param minfo
 */
void draw_char_en(int o_x, int o_y, int index, int color, uint64_t fbbase, struct mode_info* minfo) {
  for (int y = 0; y < 16; y++) {
    char byte = fonts_en[index][y];

    for (int x = 0; x < 8; x++) {
      char bit = (byte >> (7 - x)) & 0x1;
      if (bit == 1) {
        *((uint32_t*)fbbase + (o_y + y) * minfo->hres + o_x + x) = color;
      }
    }
  }
}

/**
 * Draw chinese character function
 * 
 * @param o_x     Origin point o_x of the upper left corner of the rectangle
 * @param o_y     Origin point o_y of the upper left corner of the rectangle
 * @param index   Index of fonts characters array
 * @param color
 * @param fbbase
 * @param minfo
 */
void draw_char_zh(int o_x, int o_y, int index, int color, uint64_t fbbase, struct mode_info* minfo) {
  for (int y = 0; y < 16; y++) {
    char byte_low_8 = fonts_zh[index][y*2];

    for (int x = 0; x < 8; x++) {
      char bit = (byte_low_8 >> (7 - x)) & 0x1;
      if (bit == 1) {
        *((uint32_t*)fbbase + (o_y + y) * minfo->hres + o_x + x) = color;
      }
    }

    char byte_high_8 = fonts_zh[index][y*2+1];

    for (int x = 0; x < 8; x++) {
      char bit = (byte_high_8 >> (7 - x)) & 0x1;
      if (bit == 1) {
        *((uint32_t*)fbbase + (o_y + y) * minfo->hres + o_x + 8 + x) = color;
      }
    }
  }
}

/*
* (o_x, o_y) 
*
* 0 ·--- x
*   |
*   y
*                     l
*                    150
*   (100,100) ·---------------·
*             |               |
*       w 100 |               |
*             |               |
*             ·---------------·
*/
/**
 * Draw rectangle function
 * 
 * @param o_x     Origin point o_x of the upper left corner of the rectangle
 * @param o_y     Origin point o_y of the upper left corner of the rectangle
 * @param l       Rectangle length
 * @param w       Rectangle width
 * @param color
 * @param fbbase
 * @param minfo
 */
void draw_rect(int o_x, int o_y, int l, int w, int color, uint64_t fbbase, struct mode_info* minfo) {
  for (int i = o_x; i < o_x + l; i++) { // Draw two length edges
    *((uint32_t*)fbbase + o_y * minfo->hres + i) = color;
    *((uint32_t*)fbbase + (o_y + w) * minfo->hres + i) = color;
  }
  for (int i = o_y; i < o_y + w; i++) { // Draw two width edges
    *((uint32_t*)fbbase + i * minfo->hres + o_x) = color;
    *((uint32_t*)fbbase + i * minfo->hres + o_x + l) = color;
  }
}